package com.huitong.common.mybatis.utils;

import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.huitong.common.mybatis.domain.dto.BasePageDTO;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * 分页工具类
 *
 * @author fromdrowning
 * @date 2024/4/28 下午4:42
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class PageUtils {

    /**
     * 默认分页排序字段
     */
    private static final String DEFAULT_ORDER_FIELD = "create_time";

    /**
     * 开启分页
     *
     * @param basePageDTO 分页信息
     */
    public static void startPage(BasePageDTO basePageDTO) {
        String orderField = toUnderlineOrderField(basePageDTO.getOrderField());
        PageHelper.startPage(basePageDTO.getPageNum(),
            basePageDTO.getPageSize(),
            orderField + " " + basePageDTO.getOrderRule());
    }

    /**
     * 开启分页 分页时需要进行多表连接时使用此方法并指定表名 否则MySQL无法判断排序字段是属于哪张表
     *
     * @param basePageDTO 分页信息
     * @param tableName   表名
     */
    public static void startPage(BasePageDTO basePageDTO, String tableName) {
        String orderField = toUnderlineOrderField(basePageDTO.getOrderField());
        PageHelper.startPage(basePageDTO.getPageNum(),
            basePageDTO.getPageSize(),
            tableName + "." + orderField + " " + basePageDTO.getOrderRule());
    }

    /**
     * 将小驼峰命名字段转换为下划线命名字段
     *
     * @param orderField 小驼峰命名字段
     * @return 下划线命名字段
     */
    private static String toUnderlineOrderField(String orderField) {
        if (StrUtil.isBlank(orderField)) {
            return DEFAULT_ORDER_FIELD;
        }

        StringBuilder result = new StringBuilder();
        boolean upperCase = false;

        for (int i = 0; i < orderField.length(); i++) {
            char c = orderField.charAt(i);

            if (Character.isUpperCase(c)) {
                if (i > 0 && !upperCase) {
                    result.append("_");
                }
                result.append(Character.toLowerCase(c));
                upperCase = true;
            } else {
                result.append(c);
                upperCase = false;
            }
        }

        return result.toString();
    }
}
